//
//  SerialPortSelectionData.m
//
//	Serial Remote for Mac - Control mac actions via serial commands
//	Copyright (C) 2010  Jeremiah McConnell
//
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#import "SerialPortSelectionData.h"
#import "AMSerialPortList.h"

static SerialPortSelectionData *SerialPortSelectionDataSingleton = nil;

@implementation SerialPortSelectionData

@synthesize portList;
@synthesize selectedPort;
@synthesize selectedPortRate;
@synthesize commandRepeatString;
@synthesize commandDelimiter;
@synthesize commandRepeatStringEnabled;


#pragma mark -
#pragma mark Class Methods

+ (SerialPortSelectionData *)sharedPortSlectionData
{
	@synchronized(self) {
		if (SerialPortSelectionDataSingleton == nil) {
			SerialPortSelectionDataSingleton = [[self alloc] init];
		}
	}
	return SerialPortSelectionDataSingleton;
}

#pragma mark -
#pragma mark Initialization Methods

- (id)init
{
	if ((self = [super init])) {
		// Initialize the port list
		[self setPortList:[[NSMutableArray alloc] initWithCapacity:[[[AMSerialPortList sharedPortList] serialPorts] count]]];
		
		// Bind values to user defaults
		[self bind:@"selectedPort" toObject:[NSUserDefaultsController sharedUserDefaultsController] withKeyPath:@"values.selectedPort" options:nil];
		[self bind:@"selectedPortRate" toObject:[NSUserDefaultsController sharedUserDefaultsController] withKeyPath:@"values.selectedPortRate" options:nil];
		[self bind:@"commandDelimiter" toObject:[NSUserDefaultsController sharedUserDefaultsController] withKeyPath:@"values.commandDelimiter" options:nil];
		
		// register for port add/remove notification
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(portsChanged:) name:AMSerialPortListDidAddPortsNotification object:nil];
		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(portsChanged:) name:AMSerialPortListDidRemovePortsNotification object:nil];
		
		// Update port list
		[self portsChanged:nil];
	}
	
	return self;
}

#pragma mark -
#pragma mark KVC Methods

- (NSUInteger)countOfPortList
{
	return [portList count];
}

- (id)objectInPortListAtIndex:(NSUInteger)index
{
	return [portList objectAtIndex:index];
}

- (void)insertObject:(id)anObject inPortListAtIndex:(NSUInteger)index
{
	[portList insertObject:anObject atIndex:index];
}

- (void)removeObjectFromPortListAtIndex:(NSUInteger)index
{
	[portList removeObjectAtIndex:index];
}

#pragma mark -

- (void)portsChanged:(NSNotification *)theNotification
{
	NSArray *ports = [[AMSerialPortList sharedPortList] serialPorts];
	NSMutableArray *portNames = [[NSMutableArray alloc] initWithCapacity:[ports count]]; 
	
	// Add newly created ports
	for (NSDictionary *port in ports) {
		NSString *portName = [port valueForKey:@"bsdPath"];
		
		[portNames addObject:portName];
		
		if (![portList containsObject:portName]) {
			[self insertObject:portName inPortListAtIndex:0];
		}
	}
	
	// Remove no longer present ports
	for (NSString *port in portList) {
		if (![portNames containsObject:port]) {
			[self removeObjectFromPortListAtIndex:[portList indexOfObject:port]];
		}
	}
}

@end
